﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.Xml.Serialization;

namespace OffInvoiceExcelAddIn.FacturaeFiles
{
    /// <summary>
    /// Clase utilizada para la importación de archivos en formato xml facturae a la plantilla de Word Facturae
    /// Básicamente hace lo inverso a FacturaeGenerator
    /// </summary>
    class ValueBinder
    {
        #region fields
        /// <summary>
        /// Objeto de tipo Facturae resultante de deserealizar un archivo de faturae en XML, del que se tomará la información para vincularla al documento de word
        /// </summary>
        Facturae facturae;

        /// <summary>
        /// Contiene la información de cabecera del archivo de facturae
        /// </summary>
        FileHeaderType fileHeader;

        ///// <summary>
        ///// Listado de ContentControls del documento de Word al que se vincularan los datos
        ///// </summary>
        //ContentControls controls;

        /// <summary>
        /// Contiene la información del encabezado de factura
        /// </summary>
        InvoiceHeaderType invoiceHeader;

        /// <summary>
        /// Contiene la infomacion del ó emisor de la factura
        /// </summary>
        BusinessType sellerParty;

        /// <summary>
        /// Contiene la Información del cliente o receptor de la factura
        /// </summary>
        BusinessType buyerParty;

        /// <summary>
        /// Contiene la información referente al tercero si la factura fue emitida por un ente externo
        /// </summary>
        ThirdPartyType thirdParty;


        /// <summary>
        /// Contiene la información de la factura
        /// </summary>
        InvoiceType invoice;

        /// <summary>
        /// Contiene los datos de emisión de la factura
        /// </summary>
        InvoiceIssueDataType invoiceIssueData;

        /// <summary>
        /// Listado de detalles de la factura
        /// </summary>
        List<InvoiceLineType> items;

        /// <summary>
        /// Listado de descuentos de la factura
        /// </summary>
        List<DiscountType> discounts;

        /// <summary>
        /// Contiene la información de los detalles de la factura
        /// </summary>
        InvoiceTotalsType invoiceTotals;

        /// <summary>
        /// Referencia al documento de word sobre el que se importaran los datos
        /// </summary>
        Microsoft.Office.Interop.Excel.Worksheet document;

        /// <summary>
        /// array de caracteres a eliminar de los valores tomados directamente de las celdas de una table
        /// </summary>
        char[] x = { '\r', '\a', '\n' };


        /// <summary>
        /// formato en el que viene la fecha en los archivos ed facturae.xml
        /// </summary>
        string[] format = { "dd/MM/yyyy" };

        /// <summary>
        /// indica si se importan los datos para rectificar una factura
        /// </summary>
        bool corrective;

        /// <summary>
        /// Referencia cultural utilizada para interpretar los valores numéricos del archivo xml
        /// </summary>
        CultureInfo culturaFactura;

        /// <summary>
        /// Referencia cultural instalada en el SO, utilizada para visualizar los valores en el documentos
        /// </summary>
        CultureInfo culturaOffice;

        #endregion
        /// <summary>
        /// Importa los datos de un objeto Facturae al documento de plantilla Word facturae
        /// </summary>
        /// <param name="facturae">Facturae que contiene los datos a visualizar</param>
        /// <param name="document">Documento de word sobre el que se visualizarán los datos</param>
        /// <param name="corrective">Especifica si los datos importados son para generar  una factura rectificativa</param>
        /// <param name="cultureInvoice">Referencia cultural a utilziar para visulizar los datos</param>

        public ValueBinder(Facturae facturae, Microsoft.Office.Interop.Excel.Worksheet document, bool corrective)
        {
            this.facturae = facturae;
            this.document = document;
            //this.controls = this.document.ContentControls;
            this.corrective = corrective;

            //this.cultureInvoice = cultureInvoice;

            culturaFactura = new CultureInfo("en-US");

            culturaOffice = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));


            if (facturae != null)
            {
                //inicializar elementos 
                fileHeader = facturae.FileHeader;
                invoiceHeader = facturae.Invoices[0].InvoiceHeader;
                sellerParty = facturae.Parties.SellerParty;
                buyerParty = facturae.Parties.BuyerParty;
                thirdParty = facturae.FileHeader.ThirdParty;
                //paymentsDetails = facturae.Invoices[0].PaymentDetails[0];
                invoice = facturae.Invoices[0];
                invoiceIssueData = invoice.InvoiceIssueData;
                items = invoice.Items;
                discounts = invoice.InvoiceTotals.GeneralDiscounts;
                invoiceTotals = invoice.InvoiceTotals;
                //if (facturae.Invoices[0].InvoiceHeader.Corrective != null)
                //    this.corrective = true;
                //cargar datos

                SetInvoiceHeaderData();
                SetIssuerPartyData();
                setBuyerPartyData();

                try
                {
                    setThirdPartyData();
                }
                catch (Exception)
                {
                    ControlMessages msg = ControlMessages.getInstance();
                    throw new Exception(msg.getMessage(ControlMessages.Msg.InfoThirdParty));
                }
                setAdditionalInformationData();
                setInvoiceIssueData();
                Workbook wb = Globals.ThisAddIn.Application.ActiveWorkbook;
                Globals.ThisAddIn.edit(wb, wb.Sheets[1], false);
                setItemsData();
                setDiscountData();
                setTotalsData();
                Globals.ThisAddIn.edit(wb, wb.Sheets[1], true);

                //CleanTemplate(facturae);

            }
        }

        /// <summary>
        /// Vincula al documento los datos correspondientes al encabezado de la factura
        /// </summary>
        private void SetInvoiceHeaderData()
        {
            if (invoiceHeader != null)
            {
                if (!corrective)
                {
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.IH_InvoiceSeriesCode, invoiceHeader.InvoiceSeriesCode);
                    }
                    catch (Exception)
                    {
                    }
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.IH_InvoiceNumber, invoiceHeader.InvoiceNumber);

                    if (invoiceHeader.Corrective != null)
                    {
                        try
                        {
                            Globals.ThisAddIn.setControlValue(ControlList.Tag.CORR_InvoiceSeriesCode, invoiceHeader.Corrective.InvoiceSeriesCode);
                        }
                        catch (Exception)
                        {
                        }
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.CORR_InvoiceNumber, invoiceHeader.Corrective.InvoiceNumber);
                    }

                    if (invoiceHeader.Corrective != null)
                    {
                        setCorrective(invoiceHeader.Corrective);
                    }

                }
                else
                {

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.CORR_InvoiceSeriesCode, invoiceHeader.InvoiceSeriesCode);
                    }
                    catch (Exception)
                    {
                    }
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.CORR_InvoiceNumber, invoiceHeader.InvoiceNumber);


                }
            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes al emisor de la factura
        /// </summary>
        private void SetIssuerPartyData()
        {
            if (sellerParty != null)
            {
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_PersonTypeCode, sellerParty.TaxIdentification.PersonTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_ResidenceTypeCode, sellerParty.TaxIdentification.ResidenceTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_TaxIdentificationNumber, sellerParty.TaxIdentification.TaxIdentificationNumber);
                //modificado
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.SP_PersonTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.SP_PersonTypeCode);
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.SP_ResidenceTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.SP_ResidenceTypeCode);
                //Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_TaxIdentificationNumber, sellerParty.TaxIdentification.TaxIdentificationNumber);

                if (sellerParty.TaxIdentification.PersonTypeCode.Equals(PersonTypeCodeType.F))
                {
                    IndividualType individual = (IndividualType)sellerParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Name, individual.Name);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_FirstSurname, individual.FirstSurname);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_SecondSurname, individual.SecondSurname);

                    setSP_AddressData(individual.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Telephone, individual.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {

                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_email, individual.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {

                    }

                }
                else
                {
                    LegalEntityType legalentity = (LegalEntityType)sellerParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_CorporateName, legalentity.CorporateName);

                    setSP_AddressData(legalentity.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Telephone, legalentity.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_email, legalentity.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {
                    }

                }
            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes al cliente o receptor de la factura
        /// </summary>
        private void setBuyerPartyData()
        {
            if (buyerParty != null)
            {
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.BP_PersonTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.BP_PersonTypeCode);//, buyerParty.TaxIdentification.PersonTypeCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.BP_ResidenceTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.BP_ResidenceTypeCode);//, buyerParty.TaxIdentification.ResidenceTypeCode.ToString("g"));
                //Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_TaxIdentificationNumber, buyerParty.TaxIdentification.TaxIdentificationNumber);

                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_PersonTypeCode, buyerParty.TaxIdentification.PersonTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_ResidenceTypeCode, buyerParty.TaxIdentification.ResidenceTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_TaxIdentificationNumber, buyerParty.TaxIdentification.TaxIdentificationNumber);


                if (buyerParty.TaxIdentification.PersonTypeCode.Equals(PersonTypeCodeType.F))
                {
                    IndividualType individual = (IndividualType)buyerParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Name, individual.Name);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_FirstSurname, individual.FirstSurname);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_SecondSurname, individual.SecondSurname);

                    setBP_AddressData(individual.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Telephone, individual.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_email, individual.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {
                    }

                }
                else
                {
                    LegalEntityType legalentity = (LegalEntityType)buyerParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_CorporateName, legalentity.CorporateName);

                    setBP_AddressData(legalentity.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Telephone, legalentity.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_email, legalentity.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {
                    }

                }
            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes al tercero, en caso de que el emisor de la factura, sea un ente ajeno a las partes principales
        /// </summary>
        private void setThirdPartyData()
        {
            if (thirdParty != null)
            {
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.TH_PersonTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.TH_PersonTypeCode);//, thirdParty.TaxIdentification.PersonTypeCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.TH_ResidenceTypeCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.TH_ResidenceTypeCode);//, thirdParty.TaxIdentification.ResidenceTypeCode.ToString("g"));
                //Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_TaxIdentificationNumber, thirdParty.TaxIdentification.TaxIdentificationNumber);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_PersonTypeCode, thirdParty.TaxIdentification.PersonTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_ResidenceTypeCode, thirdParty.TaxIdentification.ResidenceTypeCode.ToString());
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_TaxIdentificationNumber, thirdParty.TaxIdentification.TaxIdentificationNumber);

                if (thirdParty.TaxIdentification.PersonTypeCode.Equals(PersonTypeCodeType.F))
                {
                    IndividualType individual = (IndividualType)thirdParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Name, individual.Name);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_FirstSurname, individual.FirstSurname);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_SecondSurname, individual.SecondSurname);

                    setTH_AddressData(individual.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Telephone, individual.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Email, individual.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {
                    }

                }
                else
                {
                    LegalEntityType legalentity = (LegalEntityType)thirdParty.Item;
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_CorporateName, legalentity.CorporateName);

                    setTH_AddressData(legalentity.Item);

                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Telephone, legalentity.ContactDetails.Telephone);
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Email, legalentity.ContactDetails.ElectronicMail);
                    }
                    catch (Exception)
                    {
                    }

                }
            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes a la dirección del emisor de la factura
        /// </summary>
        /// <param name="addressItem">objeto que contiene la información de la dirección</param>
        private void setSP_AddressData(object addressItem)
        {
            try
            {
                AddressType address = (AddressType)addressItem;
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Address, address.Address);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Province, address.Province);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_PostCode, address.PostCode);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_CountryCode, address.CountryCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.SP_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.SP_CountryCode);//, address.CountryCode.ToString("g"));
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Town, address.Town);

            }
            catch (Exception)
            {
                OverseasAddressType OvAddress = (OverseasAddressType)addressItem;
                string postCode = ""; string Town = "";
                try
                {
                    foreach (char c in OvAddress.PostCodeAndTown.ToCharArray())
                    {
                        int n = int.Parse(c.ToString());
                        postCode += c.ToString();
                    }
                }
                catch (FormatException)
                {
                    Town = OvAddress.PostCodeAndTown.Substring(postCode.Length);
                }
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Address, OvAddress.Address);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Province, OvAddress.Province);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_PostCode, postCode);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_Town, Town);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.SP_CountryCode, OvAddress.CountryCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.SP_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.SP_CountryCode);//, OvAddress.CountryCode.ToString("g"));


            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes a la dirección del receptor de la factura
        /// </summary>
        /// <param name="addressItem">objeto que contiene la información de la dirección</param>
        private void setBP_AddressData(object addressItem)
        {
            try
            {
                AddressType address = (AddressType)addressItem;
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Address, address.Address);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Province, address.Province);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_PostCode, address.PostCode);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_CountryCode, address.CountryCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.BP_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.BP_CountryCode);//, address.CountryCode.ToString("g"));

                Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Town, address.Town);

            }
            catch (Exception)
            {
                {
                    OverseasAddressType OvAddress = (OverseasAddressType)addressItem;
                    string postCode = ""; string Town = "";
                    try
                    {
                        foreach (char c in OvAddress.PostCodeAndTown.ToCharArray())
                        {
                            int n = int.Parse(c.ToString());
                            postCode += c.ToString();
                        }
                    }
                    catch (FormatException)
                    {
                        Town = OvAddress.PostCodeAndTown.Substring(postCode.Length);
                    }

                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Address, OvAddress.Address);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Province, OvAddress.Province);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_PostCode, postCode);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_Town, Town);
                    Globals.ThisAddIn.setControlValue(ControlList.Tag.BP_CountryCode, OvAddress.CountryCode.ToString("g"));
                    //Globals.ThisAddIn.getControlByTag(ControlList.Tag.BP_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.BP_CountryCode);//, OvAddress.CountryCode.ToString("g"));

                }
            }
        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes a la dirección del tercero, cuando el emisor de la factura es un ente externo
        /// </summary>
        /// <param name="addressItem">objeto que contiene la información de la dirección</param>
        private void setTH_AddressData(object addressItem)
        {
            try
            {

                AddressType address = (AddressType)addressItem;
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_PostCode, address.PostCode);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Town, address.Town);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Address, address.Address);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Province, address.Province);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_CountryCode, address.CountryCode.ToString("g"));
               // Globals.ThisAddIn.getControlByTag(ControlList.Tag.TH_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.TH_CountryCode);//, address.CountryCode.ToString("g"));



            }
            catch (Exception)
            {
                OverseasAddressType OvAddress = (OverseasAddressType)addressItem;
                string postCode = ""; string Town = "";
                try
                {
                    foreach (char c in OvAddress.PostCodeAndTown.ToCharArray())
                    {
                        int n = int.Parse(c.ToString());
                        postCode += c.ToString();
                    }
                }
                catch (FormatException)
                {
                    Town = OvAddress.PostCodeAndTown.Substring(postCode.Length);
                }

                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Address, OvAddress.Address);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Province, OvAddress.Province);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_PostCode, postCode);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_Town, Town);
                Globals.ThisAddIn.setControlValue(ControlList.Tag.TH_CountryCode, OvAddress.CountryCode.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.TH_CountryCode).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.TH_CountryCode);//, OvAddress.CountryCode.ToString("g"));

            }
        }


        /// <summary>
        ///  Vincula al documento los datos correspondientes a la informacion adicional de la factura
        /// </summary>
        private void setAdditionalInformationData()
        {
            try
            {
                //document.Tables[t4].Rows[2].Range.Text = invoice.AdditionalData.InvoiceAdditionalInformation;
            }
            catch (Exception)
            {
            }

        }

        /// <summary>
        ///  Vincula al documento los datos correspondientes a los datos de emisión de la factura
        /// </summary>
        private void setInvoiceIssueData()
        {

            //CultureInfo cult = new CultureInfo("es-ES");
            Globals.ThisAddIn.setControlValue(ControlList.Tag.InvIssue_IssueDate, Convert.ToDateTime(invoiceIssueData.IssueDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            Globals.ThisAddIn.setControlValue(ControlList.Tag.InvIssue_OperationDate, Convert.ToDateTime(invoiceIssueData.OperationDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            Globals.ThisAddIn.setControlValue(ControlList.Tag.InvIssue_InvoiceCurrencyCode, facturae.FileHeader.Batch.InvoiceCurrencyCode.ToString("g"));
            Globals.ThisAddIn.setControlValue(ControlList.Tag.ExchangeRate, getExchangeRate());
            Globals.ThisAddIn.setControlValue(ControlList.Tag.InvIssue_LanguageName, invoiceIssueData.LanguageName.ToString("g"));
            Globals.ThisAddIn.setControlValue(ControlList.Tag.InvoiceIssuerType, fileHeader.InvoiceIssuerType.ToString("g"));
            //Globals.ThisAddIn.getControlByTag(ControlList.Tag.InvoiceIssuerType).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.InvoiceIssuerType);//, fileHeader.InvoiceIssuerType.ToString("g"));
            if (!corrective)
                Globals.ThisAddIn.setControlValue(ControlList.Tag.IH_InvoiceClass, invoiceHeader.InvoiceClass.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.IH_InvoiceClass).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.IH_InvoiceClass);//, invoiceHeader.InvoiceClass.ToString("g"));
            else
            {
                Globals.ThisAddIn.setControlValue(ControlList.Tag.IH_InvoiceClass, InvoiceClassType.OR.ToString("g"));
                //Globals.ThisAddIn.getControlByTag(ControlList.Tag.IH_InvoiceClass).Value2 = Globals.ThisAddIn.GetControlValue(ControlList.Tag.IH_InvoiceClass);//, InvoiceClassType.OR.ToString("g"));
            }
        }


        private string getExchangeRate()
        {
            double result = double.Parse("1", culturaOffice.NumberFormat);
            try
            {
                result = (double.Parse(facturae.FileHeader.Batch.TotalInvoicesAmount.EquivalentInEuros, culturaFactura.NumberFormat) / double.Parse(facturae.FileHeader.Batch.TotalInvoicesAmount.TotalAmount, culturaFactura.NumberFormat));
            }
            catch (Exception)
            {
            }
            return String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", result);
        }

        ///// <summary>
        ///// Busca el ContentControl llamado tag y le asigna value a la propiedad texto
        ///// </summary>
        ///// <param name="tag">Nombre del ContentControl</param>
        ///// <param name="value">Valor a asignarle como texto al ContentControl tag</param>
        //private void setControlValue(ControlList.Tag tag, string value)
        //{
        //    Object missing = Type.Missing;
        //    try
        //    {
        //        ((Range)document.get_Range(tag, missing)).Value2 = value;
        //        //foreach (Microsoft.Office.Interop.Word.ContentControl item in controls)
        //        //{
        //        //    if (!string.IsNullOrEmpty(item.Tag))
        //        //    {
        //        //        if (item.Tag.ToLower().Equals(tag.ToString("g").ToLower()))
        //        //        {
        //        //            item.Range.Text = value; break;
        //        //        }

        //        //    }
        //        //}
        //    }
        //    catch (Exception) { }
        //}

        ///// <summary>
        ///// Busca el ContentControl con el que tiene el tag especificado
        ///// </summary>
        ///// <param name="tag">tag del ContentControl buscado</param>
        ///// <returns>el ContentControl con tag = tag, null si no lo encuentra</returns>
        //private Range getControl(ControlList.Tag tag)
        //{
        //    try
        //    {
        //        return document.get_Range(tag.ToString("g"),Type.Missing);
        //    }
        //    catch (Exception) { return null; }

        //}

        /// <summary>
        /// Crea en la tabla detalles tantas filas como detalles tenga la facturae y asigna los respectivos valores
        /// </summary>
        private void setItemsData()
        {

            Object missing = Type.Missing;
            Name rngN = Globals.ThisAddIn.Application.ActiveWorkbook.Names.Item("detailLastRow", missing, missing);
            Range rng = rngN.RefersToRange;
            int fecha = ((Range)document.get_Range("Fecha", missing)).Column;
            int concepto = ((Range)document.get_Range("Concepto", missing)).Column;
            int unidades = ((Range)document.get_Range("Uds", missing)).Column;
            int precio = ((Range)document.get_Range("Precio", missing)).Column;
            int descuento = ((Range)document.get_Range("Descuento", missing)).Column;
            int iva = ((Range)document.get_Range("IVA", missing)).Column;
            int irpf = ((Range)document.get_Range("IRPF", missing)).Column;
            int baseImponible = ((Range)document.get_Range("Base_Imponible", missing)).Column;
            int importe = ((Range)document.get_Range("Importe", missing)).Column;

            try
            {
                if (items.Count > 0)
                {
                    foreach (InvoiceLineType item in items)
                    {
                        rng.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown, missing);
                        //string ini = "A" + (rng.Row - 1);
                        //string fin = "AH" + (rng.Row - 1);
                        Range ini = document.Cells[rng.Row - 1, fecha];
                        Range fin = document.Cells[rng.Row - 1, importe + ((Range)document.get_Range("Importe", missing)).Columns.Count];
                        Range rng2 = (Range)document.get_Range(ini, fin);

                        rng.Copy();
                        rng2.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
                        rng.Select();
                        rng.Copy();
                        rng2.Select();
                        document.Paste();
                        rng.ClearContents();


                        ((Range)rng2.Cells[1, fecha]).Value2 = Convert.ToDateTime(item.TransactionDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern);
                        ((Range)rng2.Cells[1, concepto]).Value2 = item.ItemDescription;

                        ((Range)rng2.Cells[1, unidades]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(item.Quantity, culturaFactura.NumberFormat));
                        ((Range)rng2.Cells[1, precio]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(item.UnitPriceWithoutTax, culturaFactura.NumberFormat));

                        double taxRate = 0;
                        double discountRate = 0;
                        double taxablebase = 0;

                        try
                        {
                            discountRate = double.Parse(item.DiscountsAndRebates[0].DiscountRate.Substring(0, item.DiscountsAndRebates[0].DiscountRate.LastIndexOf('.')), culturaFactura.NumberFormat);

                        }
                        catch (Exception)
                        {
                        }

                        ((Range)rng2.Cells[1, descuento]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", discountRate);

                        taxRate = double.Parse(item.TaxesOutputs[0].TaxRate, culturaFactura.NumberFormat);

                        ((Range)rng2.Cells[1, iva]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", taxRate);


                        taxablebase = double.Parse(item.TaxesOutputs[0].TaxableBase.TotalAmount, culturaFactura.NumberFormat);
                        double irpfTaxRate = 0;


                        try
                        {
                            irpfTaxRate = double.Parse(item.TaxesWithheld[0].TaxRate, culturaFactura.NumberFormat);

                        }
                        catch (Exception) { }

                        try
                        {
                            taxablebase = double.Parse(item.GrossAmount, culturaFactura.NumberFormat);

                        }
                        catch (Exception) { }


                        ((Range)rng2.Cells[1, irpf]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", irpfTaxRate);
                        ((Range)rng2.Cells[1, baseImponible]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", (double.Parse(item.GrossAmount, culturaFactura.NumberFormat)));
                        ((Range)rng2.Cells[1, importe]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", (double.Parse(item.GrossAmount, culturaFactura.NumberFormat) + (double.Parse(item.GrossAmount, culturaFactura.NumberFormat) * taxRate / 100) - (double.Parse(item.GrossAmount, culturaFactura.NumberFormat) * irpfTaxRate / 100)));


                        try
                        {
                            setTaxType(taxRate, ((taxablebase * taxRate) / 100), taxablebase);
                        }
                        catch (Exception) { }
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Crea en la tabla de totales, una linea para la base imponible, y otra para la cuota por cada tipo difernete
        /// de impuestos repercutivos que haya en la facturae
        /// </summary>
        /// <param name="taxRate">Porcentaje del impuesto aplicado</param>
        /// <param name="taxamount">Importe del impuesto aplicado</param>
        /// <param name="taxableBase">Base sobre la que se aplica el impuesto</param>
        private void setTaxType(double taxRate, double taxamount, double taxableBase)
        {
            try
            {
                Language language = Language.getInstance();

                Object missing = Type.Missing;

                Range totales = document.get_Range("t_totals", missing);

                Name rngN = Globals.ThisAddIn.Application.ActiveWorkbook.Names.Item("irpfLine", missing, missing);
                Range rng = rngN.RefersToRange;

                int name = ((Range)document.get_Range("IrpfName", missing)).Column;
                int value = ((Range)document.get_Range("IrpfValue", missing)).Column;

                string TB = string.Concat(language.getLabels("lbBaseAmount") + " (" + language.getLabels("lbVAT")," ", taxRate.ToString(), ")");
                string TA = string.Concat(language.getLabels("lbAmount") + " (" + language.getLabels("lbVAT")," ", taxRate.ToString(), ")");
                

                int taxRows = totales.Rows.Count - 3;
                bool asigned = false;

                int posIniTax=totales.Row+2;

                if (taxRows >= 1)
                {
                    for (int i = 1; i < taxRows; i++)
                    {
                        string amount = ((Range)document.Cells[posIniTax+i, name]).Text.Trim(x).Trim();
                        if (amount.ToLower().Equals(TB.ToLower()))
                        {
                            double tb = double.Parse(((Range)document.Cells[posIniTax + i, value]).Text.Trim(x).Trim(), culturaOffice.NumberFormat);
                            tb += taxableBase;

                            double ta = double.Parse(((Range)document.Cells[posIniTax + i + 1, value]).Text.Trim(x).Trim(), culturaOffice.NumberFormat);
                            ta += taxamount;


                            if (ta != 0)
                            {

                                ((Range)document.Cells[posIniTax + i, value]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", tb);
                                ((Range)document.Cells[posIniTax + i + 1, value]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", ta);
                            }

                            i++;
                            asigned = true;
                            break;
                        }

                    }
                    if (!asigned)
                    {
                        newTaxType(TB, TA, taxamount, taxableBase);
                    }

                }
            }
            catch (Exception) { }

        }

        /// <summary>
        /// Se utiliza para crear las lineas de los nuevos tipos de impuestos,  ya que los que tienen un mismo porcentaje, son acumulativos
        /// </summary>
        /// <param name="taxType">cadena utilzada para identificar la couta del tipo de impuesto</param>
        /// <param name="amountPrefix">cadena utiliada para identificar la base imponible del tipo de impuesto</param>
        /// <param name="taxAmount">importe del impuesto aplicado</param>
        /// <param name="taxableBase">base imponible sobre la que se aplica el impuesto</param>
        private void newTaxType(string taxType, string amountPrefix, double taxAmount, double taxableBase)
        {
            try
            {
                Object missing = Type.Missing;

                Range totales = document.get_Range("t_totals", missing);

                Name rngN = Globals.ThisAddIn.Application.ActiveWorkbook.Names.Item("irpfLine", missing, missing);
                Range rng = rngN.RefersToRange;

                int name = ((Range)document.get_Range("IrpfName", missing)).Column;
                int value = ((Range)document.get_Range("IrpfValue", missing)).Column;
                
                if (taxAmount != 0)
                {
                    rng.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown, missing);
                    string ini = "A" + (rng.Row - 1);
                    string fin = "AH" + (rng.Row - 1);
                    Range rng2 = (Range)document.get_Range(ini, fin);
                    rng.Copy();
                    rng2.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);

                    ((Range)rng2.Cells[1, name]).Value2 = taxType;
                    ((Range)rng2.Cells[1, value]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", taxableBase);

                    rng.ClearOutline();

                    rng.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown, missing);
                    ini = "A" + (rng.Row - 1);
                    fin = "AH" + (rng.Row - 1);
                    rng2 = (Range)document.get_Range(ini, fin);
                    rng.Copy();
                    rng2.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
                    ((Range)rng2.Cells[1, name]).Value2 = amountPrefix;
                    ((Range)rng2.Cells[1, value]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", taxAmount);
                    rng.ClearOutline();
                }
            }
            catch (Exception) { }
        }


        /// <summary>
        /// Encargado de generar las nuevas lineas en la tabla de descuentos generales y establecer los respectivos valores
        /// </summary>
        private void setDiscountData()
        {
            try
            {
                //CultureInfo cult = new CultureInfo("es-ES");

                if (discounts.Count > 0)
                {
                    Object missing = Type.Missing;
                    int concepto = ((Range)document.get_Range("disc_Concepto", missing)).Column;
                    int porcentaje = ((Range)document.get_Range("disc_rate", missing)).Column;
                    int importe = ((Range)document.get_Range("disc_amount", missing)).Column;

                    Name rngN = Globals.ThisAddIn.Application.ActiveWorkbook.Names.Item("discountLastRow", missing, missing);
                    Range rng = rngN.RefersToRange;

                    foreach (DiscountType item in discounts)
                    {
                        rng.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftDown, missing);
                        //string ini = "A" + (rng.Row - 1);
                        //string fin = "AH" + (rng.Row - 1);
                        Range ini = document.Cells[rng.Row - 1, concepto];
                        Range fin = document.Cells[rng.Row - 1, importe + ((Range)document.get_Range("disc_amount", missing)).Columns.Count];
                        Range rng2 = (Range)document.get_Range(ini, fin);

                        rng.Copy();
                        rng2.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
                        rng.Select();
                        rng.Copy();
                        rng2.Select();
                        document.Paste();
                        rng.ClearContents();

                        ((Range)rng2.Cells[1, concepto]).Value2 = item.DiscountReason;
                        ((Range)rng2.Cells[1, porcentaje]).Value2 = item.DiscountRate.Substring(0, item.DiscountRate.LastIndexOf('.'));
                        ((Range)rng2.Cells[1, importe]).Value2 = string.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(item.DiscountAmount, culturaFactura.NumberFormat));

                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Vincula la información de los totales de la factura, a la tabla de totales
        /// </summary>
        private void setTotalsData()
        {
            try
            {
                Object missing = Type.Missing;

                Range totales = document.get_Range("t_totals", missing);
                Name rngN = Globals.ThisAddIn.Application.ActiveWorkbook.Names.Item("irpfLine", missing, missing);
                Range rng = rngN.RefersToRange;

                int name = ((Range)document.get_Range("IrpfName", missing)).Column;
                int value = ((Range)document.get_Range("IrpfValue", missing)).Column;

                
                if (invoiceTotals != null)
                {
                    ((Range)document.Cells[totales.Row + 1, value]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(invoiceTotals.TotalGrossAmount, culturaFactura.NumberFormat));
                    try
                    {
                        ((Range)document.Cells[totales.Row + 2, value]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(invoiceTotals.TotalGeneralDiscounts, culturaFactura.NumberFormat));

                    }
                    catch (Exception)
                    {
                        ((Range)document.Cells[totales.Row + 2, value]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse("0", culturaFactura.NumberFormat));
                    }
                    ((Range)rng.Cells[1, value]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(invoiceTotals.TotalTaxesWithheld, culturaFactura.NumberFormat));
                    ((Range)document.Cells[rng.Row + 1, value]).Value2 = String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse(invoiceTotals.InvoiceTotal, culturaFactura.NumberFormat));

                }

            }
            catch (Exception) { }

        }


        //private string controlValue(ControlList.Tag tag, string selectedItem)
        //{
        //    Object missing = Type.Missing;
        //    string value = "";

        //    value = ((Range)document.get_Range(tag, missing)).Value2;
        //    //if (string.IsNullOrEmpty(tag.ToString("g")))
        //    //    return value;

        //    ///*buscamos el combobox indicado*/
        //    //foreach (ContentControl item in document.ContentControls)
        //    //{
        //    //    if (!string.IsNullOrEmpty(item.Tag))
        //    //    {
        //    //        if (item.Tag.Equals(tag.ToString("g")))
        //    //        {
        //    //            /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
        //    //            foreach (ContentControlListEntry entry in item.DropdownListEntries)
        //    //            {
        //    //                if (!string.IsNullOrEmpty(item.Tag))
        //    //                {
        //    //                    if (entry.Value.ToLower().Equals(selectedItem.ToLower()))
        //    //                    {
        //    //                        value = entry.Text; break;
        //    //                    }
        //    //                }

        //    //            } break;
        //    //        }
        //    //    }
        //    //}
        //    return value;
        //}

        private static string ConvertToString(Enum e)
        {
            // Get the Type of the enum
            Type t = e.GetType();

            // Get the FieldInfo for the member field with the enums name
            FieldInfo info = t.GetField(e.ToString("G"));

            // Check to see if the XmlEnumAttribute is defined on this field
            if (!info.IsDefined(typeof(XmlEnumAttribute), false))
            {
                // If no XmlEnumAttribute then return the string version of the enum.
                return e.ToString("G");
            }

            // Get the XmlEnumAttribute
            object[] o = info.GetCustomAttributes(typeof(XmlEnumAttribute), false);
            XmlEnumAttribute att = (XmlEnumAttribute)o[0];
            return att.Name;
        }

        public void CleanTemplate(Facturae facturae)
        {
            try
            {
                //if (!facturae.FileHeader.InvoiceIssuerType.Equals(InvoiceIssuerTypeType.TE))
                //{
                //    document.Tables[t6].Delete();
                //}
            }
            catch (Exception) { }



        }

        /// <summary>
        /// Si la clase de la factura es OR ó CR vincula al documento los datos de la rectificación
        /// </summary>
        /// <param name="correctiveData">Objeto que cntiene los datos de la rectificación</param>
        private void setCorrective(CorrectiveType correctiveData)
        {
            CorrectiveType correctiveD = correctiveData;

            try
            {
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_InvoiceNumber).Value2 = correctiveD.InvoiceNumber;
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_InvoiceSeriesCode).Value2 = correctiveD.InvoiceSeriesCode;
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_ReasonDescription).Value2 = correctiveD.ReasonDescription;
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_TaxPeriod_StartDate).Value2 = Convert.ToDateTime(correctiveD.TaxPeriod.StartDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern);
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_TaxPeriod_EndDate).Value2 = Convert.ToDateTime(correctiveD.TaxPeriod.EndDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern);
                Globals.ThisAddIn.getControlByTag(ControlList.Tag.CORR_CorrectionMethodDescription).Value2 = correctiveD.CorrectionMethodDescription;
            }
            catch (Exception)
            {
                ControlMessages msg = ControlMessages.getInstance();

                throw new Exception(msg.getMessage(ControlMessages.Msg.InfoThirdParty));
            }


        }




    }
}
